// Thud - a dynamic object-oriented language
// Copyright (C) 2009,2010 David H. Hovemeyer <david.hovemeyer@gmail.com>

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

/*
 * Token2.cpp
 *
 *  Created on: Dec 11, 2009
 *      Author: dhovemey
 */

#include <cassert>
#include "fe/Token2.h"

bool Token2::isBinOp(TokenType tt)
{
	return tt >= TOK_FIRST_BIN_OP && tt <= TOK_LAST_BIN_OP;
}

bool Token2::isBinOpOrAssign(TokenType tt)
{
	return tt == ASSIGN || isBinOp(tt);
}

int Token2::getPrecedence(TokenType tt)
{
	assert(isBinOpOrAssign(tt));
	switch(tt) {
	case ASSIGN:
		return 1;
	case LOGICAL_OR:
		return 2;
	case LOGICAL_AND:
		return 3;
	case GREATER_THAN_EQ:
	case GREATER_THAN:
	case LESS_THAN_EQ:
	case LESS_THAN:
	case NOT_EQUALS:
	case EQUALS:
		return 4;
	case MINUS:
	case PLUS:
		return 5;
	case DIVIDE:
	case TIMES:
		return 6;
	default:
		assert(false);
		return -1;
	}
}

bool Token2::isLeftAssoc(TokenType tt)
{
	assert(isBinOpOrAssign(tt));
	return tt != ASSIGN;
}

bool Token2::isRightAssoc(TokenType tt)
{
	return !isLeftAssoc(tt);
}

std::wstring Token2::getBinOpName(TokenType tt)
{
	switch (tt) {
	case ASSIGN: return L"=";
	case LOGICAL_OR: return L"||";
	case LOGICAL_AND: return L"&&";
	case GREATER_THAN_EQ: return L">=";
	case GREATER_THAN: return L">";
	case LESS_THAN_EQ: return L"<=";
	case LESS_THAN: return L"<";
	case NOT_EQUALS: return L"!=";
	case EQUALS: return L"==";
	case MINUS: return L"-";
	case PLUS: return L"+";
	case DIVIDE: return L"/";
	case TIMES: return L"*";
	default:
		assert(false);
		return L"<unknown>";
	}
}

Token2::Token2(TokenType tokenType, const std::wstring &lexeme, const Location &loc, Token2 *prev)
	: m_tokenType(tokenType)
	, m_lexeme(lexeme)
	, m_loc(loc)
	, m_prev(prev)
	, m_next(0)
{
	if (prev != 0) {
		prev->m_next = this;
	}
}

Token2::~Token2()
{
}

Token2::TokenType Token2::getTokenType() const
{
	return m_tokenType;
}

const std::wstring &Token2::getLexeme() const
{
	return m_lexeme;
}

const Location &Token2::getLocation() const
{
	return m_loc;
}
